package com.liuxinlong.modules.system.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.DepartmentDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.dao.UserGroupDao;
import com.liuxinlong.modules.dao.UserGroupRelationDao;
import com.liuxinlong.modules.entity.UserGroup;
import com.liuxinlong.modules.entity.UserGroupRelation;
import com.liuxinlong.modules.system.dto.GroupMember;
import com.liuxinlong.modules.system.dto.GroupMemberUpdateDto;
import com.liuxinlong.modules.system.dto.ImportGroupMemberDto;
import com.liuxinlong.modules.system.service.GroupService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 用户部门实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-07-08
 */
@Service
@Slf4j
public class GroupServiceImpl implements GroupService {
    @Autowired
    private UserGroupDao userGroupDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private UserGroupRelationDao userGroupRelationDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private UserDao userDao;

    @Override
    public List<Map<String, Object>> pageUserGroup(Map<String, Object> queryParam) {
        List<UserGroup> originList = userGroupDao.pageUserGroupList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (UserGroup department : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(department);
            map.put("sort", sort);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public int countUserGroup(Map<String, Object> queryParam) {
        return userGroupDao.getUserGroupCount(queryParam);
    }

    @Override
    public void addUserGroup(UserGroup userUserGroup) {
        userUserGroup.setId(SnowFlake.nextIdStr());
        userGroupDao.insert(userUserGroup);
    }

    @Override
    public void updateUserGroup(UserGroup userUserGroup) {
        userGroupDao.updateById(userUserGroup);
    }

    @Override
    public void deleteUserGroup(String id) {
        userGroupDao.deleteById(id);
    }

    @Override
    public ImportResp batchAddUserGroup(List<UserGroup> dataList) {
        for (UserGroup userGroup : dataList) {
            userGroup.setId(SnowFlake.nextIdStr());
            userGroupDao.insert(userGroup);
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setRetMessage("导入用户分组信息成功");
        return resp;
    }

    @Override
    public List<Map<String, Object>> pageGroupMember(Map<String, Object> queryParam) {
        List<GroupMember> originalList = userGroupRelationDao.pageGroupMemberList(queryParam);
        int startNum = (int) queryParam.get("startNum");
        List<Map<String, Object>> resultList = completeResult(originalList, startNum);
        return resultList;
    }

    @Override
    public int countGroupMember(Map<String, Object> queryParam) {
        return userGroupRelationDao.getGroupMemberCount(queryParam);
    }

    @Override
    public void updateGroupMembers(String groupId, List<GroupMemberUpdateDto> dataList) {
        Set<String> addSet = new HashSet<>();
        Set<String> deleteSet = new HashSet<>();
        for (GroupMemberUpdateDto dto : dataList) {
            if (dto.getType() == 1) {
                addSet.add(dto.getUserId());
                continue;
            }
            deleteSet.add(dto.getUserId());
        }
        if (!ObjectUtils.isEmpty(deleteSet)) {
            userGroupRelationDao.deleteByUserIds(groupId, deleteSet);
        }
        if (!ObjectUtils.isEmpty(addSet)) {
            List<UserGroupRelation> relationList = new ArrayList<>(addSet.size());
            for (String userId : addSet) {
                UserGroupRelation relation = new UserGroupRelation();
                relation.setId(SnowFlake.nextIdStr());
                relation.setGroupId(groupId);
                relation.setUserId(userId);
                relationList.add(relation);
            }
            userGroupRelationDao.insertBatch(relationList);
        }
    }

    @Override
    public ImportResp importUserGroup(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                UserGroup UserGroup = covertToBean(record);
                return false;
//				try {
//					UserGroupDao.addDetail(UserGroup);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入用户分组数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入用户分组数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("name", failRecord[0]);
                    item.put("sn", failRecord[1]);
                    item.put("folderPath", failRecord[2]);
                    item.put("remark", failRecord[3]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    @Override
    public ImportResp importGroupMember(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkMemberValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                ImportGroupMemberDto groupMemberDto = memberCovertToBean(record);
                return false;
//				try {
//					UserGroupDao.addDetail(UserGroup);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入用户分组成员数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入用户分组成员数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("sn", failRecord[0]);
                    item.put("name", failRecord[1]);
                    item.put("email", failRecord[2]);
                    item.put("group1", failRecord[3]);
                    item.put("group2", failRecord[4]);
                    item.put("group3", failRecord[5]);
                    item.put("group4", failRecord[6]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    @Override
    public ImportResp batchAddGroupMember(List<ImportGroupMemberDto> dataList) {
        Map<String,Map<String,String>> userMap = userDao.getUserMapBySn();
        Map<String,Map<String,String>> groupMap = userGroupDao.getGroupMapByName();
        List<UserGroupRelation> relationList = new ArrayList<>();
        List<Map> failedList = new ArrayList<>();
        List<String> deleteList = new ArrayList<>();
        int sort = 1;
        for (ImportGroupMemberDto groupMember : dataList) {
            // 匹配用户信息
            Map<String,String> userInfo = userMap.get(groupMember.getSn());
            if (ObjectUtils.isEmpty(userInfo)) {
                Map map = ObjectUtils.object2Map(groupMember);
                map.put("sort", sort);
                map.put("message", "用户不存在");
                sort++;
                failedList.add(map);
                continue;
            }
            String userId = userInfo.get("id");
            // 匹配用户分组
            if(!StringUtils.equals(groupMember.getGroup1(),"NA")) {
                UserGroupRelation relation = new UserGroupRelation();
                relation.setId(SnowFlake.nextIdStr());
                Map<String,String> groupInfo = groupMap.get(groupMember.getGroup1());
                if (ObjectUtils.isEmpty(groupInfo)) {
                    Map map = ObjectUtils.object2Map(groupMember);
                    map.put("sort", sort);
                    map.put("message", "用户组1不存在");
                    sort++;
                    failedList.add(map);
                    continue;
                }
                relation.setUserId(userId);
                relation.setGroupId(groupInfo.get("id"));
                relationList.add(relation);
            }
            if(!StringUtils.equals(groupMember.getGroup2(),"NA")) {
                UserGroupRelation relation = new UserGroupRelation();
                relation.setId(SnowFlake.nextIdStr());
                Map<String,String> groupInfo = groupMap.get(groupMember.getGroup2());
                if (ObjectUtils.isEmpty(groupInfo)) {
                    Map map = ObjectUtils.object2Map(groupMember);
                    map.put("sort", sort);
                    map.put("message", "用户组2不存在");
                    sort++;
                    failedList.add(map);
                    continue;
                }
                relation.setUserId(userId);
                relation.setGroupId(groupInfo.get("id"));
                relationList.add(relation);
            }
            if(!StringUtils.equals(groupMember.getGroup3(),"NA")) {
                UserGroupRelation relation = new UserGroupRelation();
                relation.setId(SnowFlake.nextIdStr());
                Map<String,String> groupInfo = groupMap.get(groupMember.getGroup3());
                if (ObjectUtils.isEmpty(groupInfo)) {
                    Map map = ObjectUtils.object2Map(groupMember);
                    map.put("sort", sort);
                    map.put("message", "用户组3不存在");
                    sort++;
                    failedList.add(map);
                    continue;
                }
                relation.setUserId(userId);
                relation.setGroupId(groupInfo.get("id"));
                relationList.add(relation);
            }
            if(!StringUtils.equals(groupMember.getGroup4(),"NA")) {
                UserGroupRelation relation = new UserGroupRelation();
                relation.setId(SnowFlake.nextIdStr());
                Map<String,String> groupInfo = groupMap.get(groupMember.getGroup4());
                if (ObjectUtils.isEmpty(groupInfo)) {
                    Map map = ObjectUtils.object2Map(groupMember);
                    map.put("sort", sort);
                    map.put("message", "用户组4不存在");
                    sort++;
                    failedList.add(map);
                    continue;
                }
                relation.setUserId(userId);
                relation.setGroupId(groupInfo.get("id"));
                relationList.add(relation);
            }
            deleteList.add(userId);
        }
        if (!ObjectUtils.isEmpty(deleteList)) {
            userGroupRelationDao.deleteByUserIdList(deleteList);
        }
        if (!ObjectUtils.isEmpty(relationList)) {
            userGroupRelationDao.insertBatch(relationList);
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(failedList.size() > 0 ? ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() : ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setFailedList(failedList);
        resp.setRetMessage(failedList.size() > 0 ? "导入用户分组成员信息部分成功" : "导入用户分组成员信息成功");
        return resp;
    }

    @Override
    public void exportGroupInfo(HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("用户分组导出excel.xlsx");
        List<UserGroup> groupList = userGroupDao.queryUserGroupList();
        String[] head = {"序号","用户组名称", "编码", "文件夹路径", "描述","默认用户组"};
        data.setHead(head);
        String[][] dataList = new String[groupList.size()][head.length];
        int index = 0;
        for (UserGroup item : groupList) {
            dataList[index][0] = String.valueOf(index+1);
            dataList[index][1] = item.getName();
            dataList[index][2] = item.getSn();
            dataList[index][3] = item.getFolderPath();
            dataList[index][4] = item.getRemark();
            dataList[index][5] = item.getDefaultFlag() == 1? "是" : "否";
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private UserGroup covertToBean(String[] record) {
        UserGroup userGroup = new UserGroup();
        userGroup.setName(record[0].trim());
        userGroup.setSn(record[1].trim());
        userGroup.setFolderPath(record[2].trim());
        userGroup.setRemark(record[3].trim());
        return userGroup;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("用户分组名称不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 50) {
                addRowError("用户分组名称长度不能超过50", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("用户分组编码不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 20) {
                addRowError("用户分组编码长度不能超过20", rowErrors);
            }
        }
        if (!StringUtils.isEmpty(record[2].trim())) {
            if (record[2].trim().length() > 200) {
                addRowError("描述长度不能超过200", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

    /**
     * 补全数据
     *
     * @param originList 原始数据
     * @param startNum   起始数
     * @return 补全数据列表
     */
    private List<Map<String, Object>> completeResult(List<GroupMember> originList, int startNum) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        if (ObjectUtil.isEmpty(originList)) {
            return resultList;
        }
        Map<String, Map<String, String>> departmentMap = departmentDao.getDepartmentMap();
        int index = startNum + 1;
        for (GroupMember item : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(item);
            map.put("index", index);
            if (StringUtils.isNotEmpty(item.getDepartment()) && departmentMap.containsKey(item.getDepartment())) {
                map.put("departmentName", departmentMap.get(item.getDepartment()).get("name"));
            }
            resultList.add(map);
            index++;
        }
        return resultList;
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private ImportGroupMemberDto memberCovertToBean(String[] record) {
        ImportGroupMemberDto groupMemberDto = new ImportGroupMemberDto();
        groupMemberDto.setSn(record[0].trim());
        groupMemberDto.setName(record[1].trim());
        groupMemberDto.setEmail(record[2].trim());
        groupMemberDto.setGroup1(record[3].trim());
        groupMemberDto.setGroup2(record[4].trim());
        groupMemberDto.setGroup3(record[5].trim());
        groupMemberDto.setGroup4(record[6].trim());
        return groupMemberDto;
    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkMemberValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("用户工号不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 20) {
                addRowError("用户工号长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("用户姓名不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 50) {
                addRowError("用户姓名长度不能超过50", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("用户邮箱不能为空", rowErrors);
        } else {
            if (record[2].trim().length() > 50) {
                addRowError("用户邮箱长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[3].trim())) {
            addRowError("用户组1不能为空", rowErrors);
        } else {
            if (record[3].trim().length() > 50) {
                addRowError("用户组1长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[4].trim())) {
            addRowError("用户组2不能为空", rowErrors);
        } else {
            if (record[4].trim().length() > 50) {
                addRowError("用户组2长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[5].trim())) {
            addRowError("用户组3不能为空", rowErrors);
        } else {
            if (record[5].trim().length() > 50) {
                addRowError("用户组3长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[6].trim())) {
            addRowError("用户组4不能为空", rowErrors);
        } else {
            if (record[6].trim().length() > 50) {
                addRowError("用户组4长度不能超过20", rowErrors);
            }
        }

        return rowErrors;
    }


}
